// 所有handle都仅关心请求如何处理，都以一个对象data作为参数，并且返回一个{status_code, content}
// 对正常回复，status_code = 200, content为回复内容
// 对预期的错误，正常返回，status_code按http状态码设置，content为error内容
// 对未预期的错误，handle直接抛出，http返回500状态码以及error


const service = {
    loin: require("./service/loin"),
    user: require("./service/user"),
    file: require("./service/file"),
    post: require("./service/post"),
    search: require("./service/search"),
    comment: require("./service/comment"),
    upvote: require("./service/upvote"),
    message: require("./service/message"),
    star: require("./service/star"),
    test: require("./test"),
}

handle = {};
handle["/loin/send"]            = service.loin.send_identify_code;
handle["/loin/bycode"]          = service.loin.loin_by_code;
handle["/loin/bywx"]           = service.loin.loin_by_wx;
handle["/loin/bysid"]           = service.loin.loin_by_sid;
handle["/user/update"]          = service.user.update_user;
handle["/post/add"]             = service.post.add_post;
handle["/post/del"]             = service.post.del_post;
handle["/post/update"]          = service.post.update_post;
handle["/post/addread"]         = service.post.add_read;
handle["/post/getfull"]         = service.post.get_fullpost;
handle["/comment/add"]          = service.comment.add_comment;
handle["/comment/del"]          = service.comment.del_comment;
handle["/upvote/add"]           = service.upvote.add_upvote;
handle["/upvote/del"]           = service.upvote.del_upvote;
handle["/star/add"]             = service.star.add_star;
handle["/star/del"]             = service.star.del_star;
handle["/search/posts"]         = service.search.search_fullposts;
handle["/search/comments1"]     = service.search.search_fullcomments1;
handle["/search/comments23"]    = service.search.search_fullcomments23;
handle["/message/add"]          = service.message.add_message;
handle["/message/read"]         = service.message.read_message;
handle["/message/del"]          = service.message.del_message;
handle["/message/delread"]      = service.message.del_read_message;
handle["/message/list"]         = service.message.get_message_list;
handle["/message/urnum"]        = service.message.get_unread_num;

handle["/test"]                 = service.test.test;

/**
 * 对json格式的请求进行route
 * @param {*} pathname 
 * @param {*} response 
 * @param {*} data 
 */
async function route_data(pathname, response, data) {
    if (handle[pathname]) {
        var res = await handle[pathname](data).catch(e => {
            response.writeHead(500, { // Server Error
                "Content-Type": "text/html"
            });
            response.write(e.message);
            response.end();
            console.log(`Unexpected Error at POST: ${pathname}`); 
            console.log(data);
            console.error(e);
            return 'end';
        });
        if (res == 'end') return;
        if (!res || !res.status_code) {
            response.writeHead(200);    // 无回复内容
            response.end();
        } else {
            response.writeHead(res.status_code, { // 正常回复，包括ok和其他预期的错误
                "Content-Type": "application/json"
            });
            response.write(JSON.stringify(res.content));
            response.end();
        }
    } else {
        console.log("No request handler found for " + pathname);
        response.writeHead(404, {
            "Content-Type": "text/html"
        });
        response.write("404 Not found");
        response.end();
    }
}

async function post(pathname, request, response) {
    if (pathname == '/upload') {
        service.file.upload(request, response);
    } else {
        var post_data = "";
        request.setEncoding("utf8");
        request.addListener("data", function(postDataChunk) {
            post_data += postDataChunk;
        });
        request.addListener("end", function() {
            route_data(pathname, response, JSON.parse(post_data));
        });
    }
}

/**
 * show image
 * @param {*} pathname 
 * @param {*} request 
 * @param {*} response 
 */
async function get(pathname, request, response) {
    if (pathname.match(/^\/images/)) {
        await service.file.view_image(pathname, response);
    }
}

module.exports = {
    post: post,
    get: get,
}
